package wire

import (
	"fmt"
	"github.com/go-kratos/kratos/cmd/kratos/v2/util"
	"os"
	"strings"
)

var WrieTmp = `package %s

import "github.com/google/wire"

var ProviderSet = wire.NewSet(
	// add set new
	%s,
)
`

func Gen(filename, body, pkg string) error {
	flag, err := util.PathExists(filename)
	if err != nil {
		return err
	}

	if !flag {
		content := fmt.Sprintf(WrieTmp, pkg, body)
		return os.WriteFile(filename, []byte(content), 0o644)
	}

	var isExistsNew bool
	handlers := make(map[string]struct{})
	content, err := util.AddContentToFile(filename, "var ProviderSet = wire.NewSet(", func(s string) {
		m := strings.TrimPrefix(strings.Trim(s, " "), "\t")
		if len(m) == 0 {
			return
		}
		idx := strings.Index(m, ",")
		if idx == -1 {
			return
		}
		handlers[m[:idx]] = struct{}{}
	}, func(positionStartIdx, positionEndIdx int, contents []string) []string {
		_, ok := handlers[body]
		if ok {
			return contents
		}
		for i, content := range contents[positionStartIdx:] {
			if strings.Contains(content, ")") {
				positionEndIdx = positionStartIdx + i
				break
			}
		}
		// 在接口处添加内容
		contents = append(contents[:positionEndIdx], append([]string{"\t" + body + ","}, contents[positionEndIdx:]...)...)
		isExistsNew = true
		return contents
	})
	if err != nil || !isExistsNew {
		return err
	}

	os.Remove(filename)

	return os.WriteFile(filename, []byte(content), 0o644)
}
